package main

//GF(2^8)上的乘法
func GFmul_8(a uint8, b uint8) (result uint8) {
	//a先乘b的第一位
	if (b & 1) == 1 {
		result = a
	}
	//乘完了第一位
	b >>= 1
	//开始乘后7位
	for i := 0; i < 7; i++ {
		//乘法即左移一位

		if a > 127 {
			//若a大于0b10000000，根据GF(2^8)上的乘法规则，移位后需要模生成多项式x^8+x^4+x^3+x+1
			//移位后的结果和生成多项式同次，因此可以直接做异或运算
			//由于是uint8因此最高位被舍掉，故只用与x^4+x^3+x+1异或，即0x1b
			a = (a << 1) ^ 0x1b
		} else {
			//小于直接移位即可
			a <<= 1
		}
		if (b & 1) == 1 {
			//乘b的第i+1位
			result ^= a
		}
		// a b = d mod c
		// a b^2 = d b mod c
		b >>= 1
	}

	return result
}

//GF(2^128)上的乘法
//输入为两个[16]byte数组
func GFmul_128(a []byte, b []byte) (result []byte) {
	//a先乘b的第一位
	if (b[0] & 1) == 1 {
		result = a
	}
	//乘完了第一位
	b >>= 1
	//开始乘后7位
	for i := 0; i < 7; i++ {
		//乘法即左移一位

		if a > 127 {
			//若a大于0b10000000，根据GF(2^8)上的乘法规则，移位后需要模生成多项式x^8+x^4+x^3+x+1
			//移位后的结果和生成多项式同次，因此可以直接做异或运算
			//由于是uint8因此最高位被舍掉，故只用与x^4+x^3+x+1异或，即0x1b
			a = (a << 1) ^ 0x1b
		} else {
			//小于直接移位即可
			a <<= 1
		}
		if (b & 1) == 1 {
			//乘b的第i+1位
			result ^= a
		}
		// a b = d mod c
		// a b^2 = d b mod c
		b >>= 1
	}

	return result
}
